/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.suli.inventory.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mchange.v3.concurrent.BoundedExecutorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.entity.Result;
import me.zhengjie.modules.mnt.websocket.MsgType;
import me.zhengjie.modules.mnt.websocket.SocketMsg;
import me.zhengjie.modules.mnt.websocket.WebSocketServer;
import me.zhengjie.suli.inventory.domain.Inventory;
import me.zhengjie.suli.inventory.domain.TallyTasks;
import me.zhengjie.suli.inventory.repository.InventoryRepository;
import me.zhengjie.suli.inventory.repository.TallyTasksRepository;
import me.zhengjie.suli.inventory.service.InventoryService;
import me.zhengjie.suli.inventory.service.dto.InventoryDto;
import me.zhengjie.suli.inventory.service.dto.InventoryQueryCriteria;
import me.zhengjie.suli.inventory.service.mapstruct.InventoryMapper;
import me.zhengjie.suli.location.domain.Location;
import me.zhengjie.suli.location.repository.LocationRepository;
import me.zhengjie.suli.outHouse.domain.Orders;
import me.zhengjie.suli.tasks.domain.TaskDetail;
import me.zhengjie.suli.tasks.domain.Tasks;
import me.zhengjie.suli.tasks.repository.TaskDetailRepository;
import me.zhengjie.suli.tasks.repository.TasksRepository;
import me.zhengjie.suli.tasks.service.TasksService;
import me.zhengjie.suli.toHouse.service.ReceiptService;
import me.zhengjie.suli.wcs.domain.AgvTaskDetail;
import me.zhengjie.suli.wcs.domain.AgvTasks;
import me.zhengjie.suli.wcs.repository.AgvTaskDetailRepository;
import me.zhengjie.suli.wcs.repository.AgvTasksRepository;
import me.zhengjie.util.CommonUtil;
import me.zhengjie.util.UuidUtil;
import me.zhengjie.utils.*;
import org.checkerframework.checker.units.qual.K;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author WYH
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2024-02-01
 **/
@Service
@Slf4j
@RequiredArgsConstructor
public class InventoryServiceImpl implements InventoryService {
    @Autowired
    private TallyTasksRepository tallyTasksRepository;
    @Autowired
    private AgvTaskDetailRepository agvTaskDetailRepository;

    private final InventoryRepository inventoryRepository;
    private final InventoryMapper inventoryMapper;
    private final TasksRepository tasksRepository;
    private final TaskDetailRepository taskDetailRepository;
    private final CommonUtil commonUtil;
    private final ReceiptService receiptService;
    private final LocationRepository locationRepository;
    private final AgvTasksRepository agvTasksRepository;
    @Autowired
    JdbcTemplate jdbcTemplate;

    @Value("${agv.port}")
    private String agvPort;

    @Value("${agv.ip}")
    private String agvIp;

    @Override
    public Map<String, Object> queryAll(InventoryQueryCriteria criteria, Pageable pageable) {
        Page<Inventory> page = inventoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(inventoryMapper::toDto));
    }

    @Override
    public List<InventoryDto> queryAll(InventoryQueryCriteria criteria) {
        return inventoryMapper.toDto(inventoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public InventoryDto findById(String id) {
        Inventory inventory = inventoryRepository.findById(id).orElseGet(Inventory::new);
        ValidationUtil.isNull(inventory.getId(), "Inventory", "id", id);
        return inventoryMapper.toDto(inventory);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public InventoryDto create(Inventory resources) {
        return inventoryMapper.toDto(inventoryRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Inventory resources) {
        Inventory inventory = inventoryRepository.findById(resources.getId()).orElseGet(Inventory::new);
        ValidationUtil.isNull(inventory.getId(), "Inventory", "id", resources.getId());
        inventory.copy(resources);
        inventoryRepository.save(inventory);
    }

    @Override
    public void deleteAll(String[] ids) {
        for (String id : ids) {
            inventoryRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<InventoryDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        all = all.stream().sorted(Comparator.comparing(InventoryDto::getMaterialCode)).collect(Collectors.toList());
        for (InventoryDto inventory : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("物料名称", inventory.getMaterialName());
            map.put("物料编码", inventory.getMaterialCode());
            map.put("可用数量", inventory.getAvailableQuantity().intValue());
            map.put("仓库", inventory.getZoneCode());
            map.put("制造时间", inventory.getElMkDate());
            map.put("批次号", inventory.getLotCode());
            map.put("箱号", inventory.getBoxNumber());
            map.put("库位", inventory.getWarehouseLocation());
            map.put("vmi标识", inventory.getVmiCode());
            map.put("供应商代码", inventory.getSuNo());
            map.put("供应商名称", inventory.getSuName());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Result selectSupplier(String codes) {
        List<String> codeList = JSON.parseArray(codes, String.class);
        List<String> collect1 = codeList.stream().distinct().collect(Collectors.toList());
        List<Inventory> byMaterialCodes = inventoryRepository.findByMaterialCodes(codeList.stream().filter(item -> !item.equals("2P17S225ANQ(-MR)")).collect(Collectors.toList()));
        List<JSONObject> jsonObjects = new ArrayList<>();
        for (String s : collect1) {
            if (s.equals("2P17S225ANQ(-MR)")) {
                continue;
            }
            JSONObject jsonObject = new JSONObject();
            List<Inventory> collect = byMaterialCodes.stream().filter(item -> item.getMaterialCode().equals(s)).collect(Collectors.toList());
            if (null == codeList || codeList.size() == 0) {
                continue;
            }
            jsonObject.put("name", "物料名称：" + collect.stream().map(Inventory::getMaterialName).findFirst().orElse(null) + "物料编码：" + s);
            jsonObject.put("code", collect.stream().map(Inventory::getSuNo).distinct().collect(Collectors.toList()));
            jsonObject.put("suName", collect.stream().map(Inventory::getSuName).distinct().collect(Collectors.toList()));
            jsonObject.put("mCode", s);
            jsonObjects.add(jsonObject);
        }

        return new Result(200, "success", jsonObjects);
    }

    @Override
    public String noOutBound(String param, String type) {
        Snowflake snowflake = new Snowflake();
        List<JSONObject> jsonObjects = JSON.parseArray(param, JSONObject.class);
        String mrList = jsonObjects.get(0).getString("mr_list");
        Tasks bySourceCodeTop = tasksRepository.findBySourceCodeTop(mrList);
        if (null != bySourceCodeTop) {
            return null;
        }
        List<TaskDetail> taskDetailList = new ArrayList<>();
        Tasks tasks = new Tasks();
        tasks.setId(snowflake.nextIdStr());
        tasks.setStatus(1);
        tasks.setSourceCode(mrList);
        if (type.equals("冻结")) {
            tasks.setTaskType(14);
        } else if (type.equals("解冻")) {
            tasks.setTaskType(15);
        } else if (type.equals("VMI转自由")) {
            tasks.setTaskType(16);
        } else if (type.equals("自由转VMI")) {
            tasks.setTaskType(17);
        }
        for (JSONObject jsonObject : jsonObjects) {
            TaskDetail taskDetail = new TaskDetail();
            taskDetail.setId(snowflake.nextIdStr());
            taskDetail.setStatus(1);
            taskDetail.setTaskId(tasks.getId());
            taskDetail.setEl_no(jsonObject.getString("el_no"));
            taskDetail.setElName(jsonObject.getString("el_name"));
            taskDetail.setLotNo(jsonObject.getString("lot_no"));
            taskDetail.setZoneCode(jsonObject.getString("mt_area"));//从库位
            taskDetail.setWaNo(jsonObject.getString("mt_tarea"));//至库位
            taskDetail.setToGender(jsonObject.getString("bin_tno"));//至等级
            taskDetail.setVmiCode(jsonObject.getString("vmi_code"));//vmi
            taskDetail.setPkQty(jsonObject.getBigDecimal("mr_qty"));//数量
            taskDetailList.add(taskDetail);
        }
        taskDetailRepository.saveAll(taskDetailList);
        tasksRepository.save(tasks);
        return mrList;
    }

    //冻结
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject freeze(String param) {

        Tasks tasks = tasksRepository.findBySourceCodeTop(param);
        if (null != tasks.getStatus() && tasks.getStatus() == 2) {
            return null;
        }
        List<TaskDetail> taskDetailList = taskDetailRepository.getTaskDetailsByTaskId(tasks.getId());
        List<Inventory> inventories = new ArrayList<>();
        List<JSONObject> jsonObjectList = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetailList) {
            if (taskDetail.getStatus() == 2) {
                continue;
            }
            List<Inventory> byTrayCode = inventoryRepository.findByLotNoAndElNo(taskDetail.getLotNo(), taskDetail.getEl_no(), taskDetail.getZoneCode());
            for (Inventory inventory : byTrayCode) {
                inventory.setGrade(taskDetail.getToGender());
                inventory.setVmiCode(taskDetail.getVmiCode());
                inventory.setZoneCode(taskDetail.getWaNo());
                inventory.setIsHold(2);
                inventory.setHoldQuantity(inventory.getAvailableQuantity());
                inventory.setAvailableQuantity(new BigDecimal(0));
                inventories.add(inventory);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("el_no", inventory.getMaterialCode());
                jsonObject1.put("mr_list", tasks.getSourceCode());
                jsonObject1.put("lot_no", inventory.getLotCode());
                jsonObject1.put("pk_qty", inventory.getHoldQuantity());
                jsonObject1.put("pk_list", inventory.getBoxNumber());
                jsonObject1.put("rtd_user", "admin");
                jsonObjectList.add(jsonObject1);
            }
            taskDetail.setStatus(2);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Sjson", JSON.toJSONString(jsonObjectList));
        log.info("冻结发送给SCCS：" + jsonObject);
        String s = commonUtil.httpPost("http://137.40.151.241:9527/RTDSXWMS/WMSImportMR03", jsonObject.toJSONString());
        String resp = StrUtil.strip(s, "\"").replaceAll("\\\\", "");
        JSONObject sccsReturn = JSON.parseObject(resp);
        if (sccsReturn.getBoolean("tran_flg")) {
            tasks.setStatus(2);
            tasksRepository.save(tasks);
            taskDetailRepository.saveAll(taskDetailList);
            inventoryRepository.saveAll(inventories);
        } else {
            throw new RuntimeException("接口调用异常");
        }
        return null;
    }

    //解冻
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject thaw(String param) {
        Tasks tasks = tasksRepository.findBySourceCodeTop(param);
        if (null != tasks.getStatus() && tasks.getStatus() == 2) {
            return null;
        }
        List<TaskDetail> taskDetailList = taskDetailRepository.getTaskDetailsByTaskId(tasks.getId());
        List<Inventory> inventories = new ArrayList<>();
        List<JSONObject> jsonObjectList = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetailList) {
            if (taskDetail.getStatus() == 2) {
                continue;
            }
            List<Inventory> byTrayCode = inventoryRepository.thawSelect(taskDetail.getLotNo(), taskDetail.getEl_no(), taskDetail.getZoneCode());
            for (Inventory inventory : byTrayCode) {
                inventory.setGrade(taskDetail.getToGender());
                inventory.setVmiCode(taskDetail.getVmiCode());
                inventory.setZoneCode(taskDetail.getWaNo());
                inventory.setIsHold(0);
                inventory.setAvailableQuantity(inventory.getAvailableQuantity().add(inventory.getHoldQuantity()));
                inventory.setHoldQuantity(new BigDecimal(0));
                inventories.add(inventory);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("el_no", inventory.getMaterialCode());
                jsonObject1.put("mr_list", tasks.getSourceCode());
                jsonObject1.put("lot_no", inventory.getLotCode());
                jsonObject1.put("pk_qty", inventory.getAvailableQuantity());
                jsonObject1.put("pk_list", inventory.getBoxNumber());
                jsonObject1.put("rtd_user", "admin");
                jsonObjectList.add(jsonObject1);
            }
            taskDetail.setStatus(2);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Sjson", JSON.toJSONString(jsonObjectList));
        log.info("解冻发送给SCCS：" + jsonObject);
        String s = commonUtil.httpPost("http://137.40.151.241:9527/RTDSXWMS/WMSImportMR03", jsonObject.toJSONString());
        String resp = StrUtil.strip(s, "\"").replaceAll("\\\\", "");
        JSONObject sccsReturn = JSON.parseObject(resp);
        if (sccsReturn.getBoolean("tran_flg")) {
            tasks.setStatus(2);
            tasksRepository.save(tasks);
            taskDetailRepository.saveAll(taskDetailList);
            inventoryRepository.saveAll(inventories);
        } else {
            throw new RuntimeException("接口调用异常");
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject free(String param) {

        Tasks tasks = tasksRepository.findBySourceCodeTop(param);
        if (null != tasks.getStatus() && tasks.getStatus() == 2) {
            return null;
        }
        List<TaskDetail> taskDetailList = taskDetailRepository.getTaskDetailsByTaskId(tasks.getId());
        List<JSONObject> jsonObjectList = new ArrayList<>();
        List<Inventory> inventories = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetailList) {
            if (taskDetail.getStatus() == 2) {
                continue;
            }
            if (!taskDetail.getZoneCode().equals("0016") && !taskDetail.getZoneCode().equals("0015") && !taskDetail.getZoneCode().equals("S015") && !taskDetail.getZoneCode().equals("S016")) {
                throw new RuntimeException("VMI转自由从库位不在本仓库");
            }
            if (!taskDetail.getWaNo().equals("0016") && !taskDetail.getWaNo().equals("0015") && !taskDetail.getWaNo().equals("S015") && !taskDetail.getWaNo().equals("S016")) {
                throw new RuntimeException("VMI转自由至库位不在本仓库");
            }
            List<Inventory> byTrayCode = inventoryRepository.findByLotNoAndElNoAndNotVmi(taskDetail.getEl_no(), taskDetail.getZoneCode(), taskDetail.getSuNo());
            byTrayCode = byTrayCode.stream().sorted(Comparator.comparing(item -> Integer.valueOf(item.getElMkDate().replaceAll("/", "")))).collect(Collectors.toList());
            BigDecimal count = taskDetail.getPkQty();
            for (Inventory inventory : byTrayCode) {
                if (count.compareTo(new BigDecimal(0)) <= 0) {
                    break;
                }
                boolean flag = false;
                if (null != inventories && inventories.size() > 0) {
                    for (Inventory inventory1 : inventories) {
                        if (inventory1.getId().equals(inventory.getId())) {
                            flag = true;
                        }
                    }
                }
                if (flag) {
                    continue;
                }
                inventory.setGrade(taskDetail.getToGender());
                inventory.setVmiCode("");
                inventory.setZoneCode(taskDetail.getWaNo());
                LocalDate localDate = LocalDate.now();
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
                String time = localDate.format(dateTimeFormatter);
                inventory.setElMkDate(time);
                inventories.add(inventory);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("el_no", inventory.getMaterialCode());
                jsonObject1.put("mr_list", tasks.getSourceCode());
                jsonObject1.put("lot_no", inventory.getLotCode());
                jsonObject1.put("pk_qty", inventory.getAvailableQuantity());
                jsonObject1.put("pk_list", inventory.getBoxNumber());
                jsonObject1.put("rtd_user", "admin");
                jsonObjectList.add(jsonObject1);
                count = count.subtract(inventory.getAvailableQuantity());
            }
            taskDetail.setStatus(2);
        }
        JSONObject jsonObject = new JSONObject();


        jsonObject.put("Sjson", JSON.toJSONString(jsonObjectList));
        log.info("VMI转自由仓发送给SCCS：" + jsonObject);
        String s = commonUtil.httpPost("http://137.40.151.241:9527/RTDSXWMS/WMSImportMR03", jsonObject.toJSONString());
        String resp = StrUtil.strip(s, "\"").replaceAll("\\\\", "");
        JSONObject sccsReturn = JSON.parseObject(resp);
        if (sccsReturn.getBoolean("tran_flg")) {
            tasks.setStatus(2);
            tasksRepository.save(tasks);
            taskDetailRepository.saveAll(taskDetailList);
            inventoryRepository.saveAll(inventories);
        } else {
            log.info("VMI转自由仓接口调用异常，返回结果:" + resp);
            throw new RuntimeException("接口调用异常");
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject freeToVmi(String param) {
        Tasks tasks = tasksRepository.findBySourceCodeTop(param);
        if (null != tasks.getStatus() && tasks.getStatus() == 2) {
            return null;
        }
        List<TaskDetail> taskDetailList = taskDetailRepository.getTaskDetailsByTaskId(tasks.getId());
        List<JSONObject> jsonObjectList = new ArrayList<>();
        List<Inventory> inventories = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetailList) {
            if (taskDetail.getStatus() == 2) {
                continue;
            }
            if (!taskDetail.getWaNo().equals("0016") && !taskDetail.getWaNo().equals("0015") && !taskDetail.getWaNo().equals("S015") && !taskDetail.getWaNo().equals("S016")) {
                throw new RuntimeException("自由转VMI至库位不在本仓库");
            }
            if (!taskDetail.getZoneCode().equals("0016") && !taskDetail.getZoneCode().equals("0015") && !taskDetail.getZoneCode().equals("S015") && !taskDetail.getZoneCode().equals("S016")) {
                throw new RuntimeException("自由转VMI从库位不在本仓库");
            }
            List<Inventory> byTrayCode = inventoryRepository.findByLotNoAndElNoAndVmi(taskDetail.getEl_no(), taskDetail.getZoneCode());
            byTrayCode = byTrayCode.stream().sorted(Comparator.comparing(item -> Integer.valueOf(item.getElMkDate().replaceAll("/", "")))).collect(Collectors.toList());
            BigDecimal count = taskDetail.getPkQty();
            for (Inventory inventory : byTrayCode) {
                if (count.compareTo(new BigDecimal(0)) <= 0) {
                    break;
                }
                if (null != inventories && inventories.size() > 0 && null == inventories.stream().filter(item -> item.getId().equals(inventory.getId())).findFirst().orElse(null)) {
                    continue;
                }
                inventory.setGrade(taskDetail.getToGender());
                inventory.setVmiCode(taskDetail.getVmiCode());
                inventory.setZoneCode(taskDetail.getWaNo());
                inventory.setSuNo(taskDetail.getSuNo());
                inventories.add(inventory);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("el_no", inventory.getMaterialCode());
                jsonObject1.put("mr_list", tasks.getSourceCode());
                jsonObject1.put("lot_no", inventory.getLotCode());
                jsonObject1.put("pk_qty", inventory.getAvailableQuantity());
                jsonObject1.put("pk_list", inventory.getBoxNumber());
                jsonObject1.put("rtd_user", "admin");
                jsonObjectList.add(jsonObject1);
                count = count.subtract(inventory.getAvailableQuantity());
            }
            taskDetail.setStatus(2);
        }


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Sjson", JSON.toJSONString(jsonObjectList));
        log.info("自由仓转VMI发送给SCCS：" + jsonObject);
        String s = commonUtil.httpPost("http://137.40.151.241:9527/RTDSXWMS/WMSImportMR03", jsonObject.toJSONString());
        String resp = StrUtil.strip(s, "\"").replaceAll("\\\\", "");
        JSONObject sccsReturn = JSON.parseObject(resp);
        if (sccsReturn.getBoolean("tran_flg")) {
            tasks.setStatus(2);
            tasksRepository.save(tasks);
            taskDetailRepository.saveAll(taskDetailList);

            inventoryRepository.saveAll(inventories);
        } else {
            log.info("自由仓转VMI接口调用异常，返回结果:" + resp);
            throw new RuntimeException("接口调用异常");
        }
        return null;
    }

    @Override
    public JSONObject notRestricted(String param) {
        List<JSONObject> jsonObjects = JSON.parseArray(param, JSONObject.class);
        List<JSONObject> jsonObjectList = new ArrayList<>();
        List<Inventory> inventories = new ArrayList<>();
        List<Tasks> taskList = new ArrayList<>();
        List<TaskDetail> taskDetailList = new ArrayList<>();
        for (JSONObject jsonObject : jsonObjects) {
//            BigDecimal count = jsonObject.getBigDecimal("mr_qty");
//            if(jsonObject.getString("mt_area").equals("0015") || jsonObject.getString("mt_area").equals("B015") || jsonObject.getString("mt_area").equals("S015")){
//                List<Inventory> inventoryList = inventoryRepository.findByLotNoAndElNoAndVmiAAndNotIsHoldAndWaNo(jsonObject.getString("lot_no"), jsonObject.getString("el_no"), jsonObject.getString("mt_area"));
//
//            }
            List<Inventory> byTrayCode = inventoryRepository.findByLotNoAndElNoAndVmiAAndNotIsHold(jsonObject.getString("lot_no"), jsonObject.getString("el_no"), jsonObject.getString("mt_area"));
            BigDecimal count = jsonObject.getBigDecimal("mr_qty");
            Snowflake snowflake = new Snowflake();
            Tasks tasks = new Tasks();
            tasks.setId(snowflake.nextIdStr());
            tasks.setSourceCode(jsonObject.getString("mr_list"));
            tasks.setStatus(2);
            tasks.setStartTime(new Timestamp(new Date().getTime()));
            tasks.setElNo(jsonObject.getString("el_no"));
            tasks.setElName(jsonObject.getString("el_name"));
            tasks.setMtQty(count);
            taskList.add(tasks);
            for (Inventory inventory : byTrayCode) {
                if (count.compareTo(new BigDecimal(0)) <= 0) {
                    break;
                }
                TaskDetail taskDetail = new TaskDetail();
                taskDetail.setFromGender(inventory.getGrade());
                inventory.setGrade(jsonObject.getString("bin_tno"));
                inventory.setVmiCode(jsonObject.getString("vmi_code"));
                inventory.setWaNo(jsonObject.getString("mt_tarea"));
                inventories.add(inventory);
                taskDetail.setToGender(inventory.getGrade());
                taskDetail.setCreateBy("admin");
                taskDetail.setLotNo(inventory.getLotCode());
                taskDetail.setWaNo(inventory.getWaNo());
                taskDetail.setPkQty(inventory.getHoldQuantity());
                taskDetail.setId(snowflake.nextIdStr());
                taskDetail.setTaskId(tasks.getId());
                taskDetail.setPkList(inventory.getBoxNumber());
                taskDetail.setVmiCode(inventory.getVmiCode());
                taskDetail.setSuNo(inventory.getSuNo());
                taskDetailList.add(taskDetail);
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("el_no", inventory.getMaterialCode());
                jsonObject1.put("mr_list", jsonObject.get("mr_list"));
                jsonObject1.put("lot_no", inventory.getLotCode());
                jsonObject1.put("pk_qty", inventory.getAvailableQuantity());
                jsonObject1.put("pk_list", inventory.getBoxNumber());
                jsonObject1.put("rtd_user", "admin");
                jsonObjectList.add(jsonObject1);
                count = count.subtract(inventory.getAvailableQuantity());
            }
        }
        inventoryRepository.saveAll(inventories);
        tasksRepository.saveAll(taskList);
        taskDetailRepository.saveAll(taskDetailList);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Sjson", JSON.toJSONString(jsonObjectList));
        log.info("发送给SCCS：" + jsonObject);
        String s = commonUtil.httpPost("http://137.40.151.241:9527/RTDSXWMS/WMSImportMR03", jsonObject);
        String resp = StrUtil.strip(s, "\"").replaceAll("\\\\", "");
        JSONObject sccsReturn = JSON.parseObject(resp);
        if (sccsReturn.getBoolean("tran_flg")) {

            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("message", "success");
            return jsonObject1;
        }
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("message", "调用接口异常");
        return jsonObject1;
    }

    @Override
    public List<Map<String, Object>> getInventoryLot(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        String materialCode = jsonObject.getString("materialCode");
        String locationCode = jsonObject.getString("locationCode");
        String warehouseCode = jsonObject.getString("warehouseCode");
        String trayCode = jsonObject.getString("trayCode");
        String materialName = jsonObject.getString("materialName");
        String lotCode = jsonObject.getString("lotCode");
        String grade = jsonObject.getString("grade");
        String pkList = jsonObject.getString("boxNumber");
        String warehouseLocation = jsonObject.getString("warehouseLocation");
        String zoneCode = jsonObject.getString("zoneCode");
        String queryCondition = getWhereCondition(warehouseLocation, locationCode, warehouseCode, trayCode, materialName, materialCode, lotCode, grade, pkList, zoneCode);
        String sql = "select material_code, lot_code, zone_code, sum(available_quantity) as available_quantity, sum(hold_quantity) as hold_quantity, SUM ( hold_quantity ) +  SUM(available_quantity) as total from inventory " +
                queryCondition + " group by lot_code,zone_code, material_code ";
//        List<Map<String, Object>> inventories = inventoryRepository.findInventoriesByMaterialCode(materialCode);
        List<Map<String, Object>> inventories = jdbcTemplate.queryForList(sql);
        return inventories;
    }

    @Override
    public List<Map<String, Object>> getInventoryBox(String data) {
        JSONObject jsonObject = JSON.parseObject(data);
        String materialCode = jsonObject.getString("materialCode");
        String locationCode = jsonObject.getString("locationCode");
        String warehouseCode = jsonObject.getString("warehouseCode");
        String trayCode = jsonObject.getString("trayCode");
        String materialName = jsonObject.getString("materialName");
        String lotCode = jsonObject.getString("lotCode");
        String grade = jsonObject.getString("grade");
        String pkList = jsonObject.getString("boxNumber");
        String warehouseLocation = jsonObject.getString("warehouseLocation");
        String zoneCode = jsonObject.getString("zoneCode");
        String queryCondition = getWhereCondition(warehouseLocation, locationCode, warehouseCode, trayCode, materialName, materialCode, lotCode, grade, pkList, zoneCode);
        String sql = "select * from inventory " +
                queryCondition;
//        List<Inventory> inventories = inventoryRepository.findInventoriesByMaterialCodeAndLotCode(materialCode, lotCode);
        List<Map<String, Object>> inventories = jdbcTemplate.queryForList(sql);
        return inventories;
    }

    @Override
    public String checkCountByLotCodeUpdateCount(Integer count) {
        String trayCode = receiptService.getTrayCode();
        if (null != trayCode && !trayCode.equals("")) {
            Inventory inventory = inventoryRepository.findByTrayCodeTop(trayCode);
            BigDecimal bigDecimal = BigDecimal.valueOf(count);
            inventory.setAvailableQuantity(bigDecimal);
            inventoryRepository.save(inventory);
            return "修正成功";
        }
        return "当前拣选位无料箱，请检查";
    }

    @Override
    public String returnLocationZanCun() {
        String trayCode = receiptService.getTrayCode();
        if (null == trayCode || "".equals(trayCode)) {
            return "当前位置无料箱";
        }
        Location location = locationRepository.findByTrayCode(trayCode);
        if (null == location) {
            return "当前位置料箱号为：" + trayCode + "请核查";
        }
        Snowflake snowflake = new Snowflake();
        String snowId = snowflake.nextIdStr();
        AgvTasks agvTasks = new AgvTasks();
        agvTasks.setId(UuidUtil.genCode());
        agvTasks.setBillNumber(snowId);
        agvTasks.setTaskType("空料箱回库");
        agvTasks.setCreateTime(new Timestamp(new Date().getTime()));
        agvTasksRepository.save(agvTasks);
        JSONObject jsonObjects = new JSONObject();
        jsonObjects.put("taskType", "putaway");
//        jsonObjects.put("groupPriority", 1);
        jsonObjects.put("taskGroupCode", UuidUtil.genCode());
        List<JSONObject> tasks = new ArrayList<>();
        JSONObject jsonObject1 = new JSONObject();
        JSONObject task = new JSONObject();
        task.put("taskCode", snowId);
        Tasks tasks1 = new Tasks();
        tasks1.setId(snowflake.nextIdStr());
        tasks1.setTaskCode(task.getString("taskCode"));
        tasks1.setTaskType(9);
        tasksRepository.save(tasks1);
        task.put("taskPriority", 1);
        jsonObject1.put("containerCode", location.getTrayCode());
        jsonObject1.put("storageTag", "");
        jsonObject1.put("toLocationCode", location.getLocationCode());
        task.put("taskDescribe", jsonObject1);
        tasks.add(task);
        jsonObjects.put("tasks", tasks);
        System.out.println("出暂存区的空料箱回库发送给AGV" + jsonObjects.toJSONString());
        String url = "http://" + agvIp + ":" + agvPort + "/task/create";
        String s = commonUtil.httpPost(url, JSON.toJSONString(jsonObjects));
        JSONObject jsonObject = JSON.parseObject(s);
        if (jsonObject.getInteger("code") == 0) {
            JSONObject jsonObject2 = new JSONObject();
            if (SecurityUtils.getCurrentUsername().equals("admin")) {
                jsonObject2.put("slotCode", "1-5");
            } else {
                jsonObject2.put("slotCode", "2-5");
            }
            jsonObject2.put("containerCode", location.getTrayCode());
            jsonObject2.put("direction", "100");
            String sp = commonUtil.httpPost("http://" + agvIp + ":" + agvPort + "/conveyor/moveContainer", jsonObject2.toJSONString());
            location.setStatus(2);
            locationRepository.save(location);
        }
        return "success";
    }

    @Override
    public List<Inventory> outBoundByZanCunSelect() {
        return inventoryRepository.findByNotHold();
    }

    @Override
    public List<Inventory> queryOutZanCunByCondition(String param) {
        JSONObject jsonObject = JSON.parseObject(param);
        String elNo;
        String lotCode;
        String zoneCode;
        if (null != jsonObject.getString("elNo") && !"".equals(jsonObject.getString("elNo"))) {
            elNo = jsonObject.getString("elNo");
        } else {
            elNo = "";
        }
        if (null != jsonObject.getString("lotCode") && !"".equals(jsonObject.getString("lotCode"))) {
            lotCode = jsonObject.getString("lotCode");
        } else {
            lotCode = "";
        }
        if (null != jsonObject.getString("zoneCode") && !"".equals(jsonObject.getString("zoneCode"))) {
            zoneCode = jsonObject.getString("zoneCode");
        } else {
            zoneCode = "";
        }
        List<Inventory> inventoryList = inventoryRepository.findByNotHold();
        if (!"".equals(elNo)) {
            inventoryList = inventoryList.stream().filter(item -> null != item.getMaterialCode() && item.getMaterialCode().equals(elNo)).collect(Collectors.toList());
        }
        if (!"".equals(lotCode)) {
            inventoryList = inventoryList.stream().filter(item -> null != item.getLotCode() && item.getLotCode().equals(lotCode)).collect(Collectors.toList());
        }
        if (!"".equals(zoneCode)) {
            inventoryList = inventoryList.stream().filter(item -> null != item.getZoneCode() && item.getZoneCode().equals(zoneCode)).collect(Collectors.toList());
        }
        return inventoryList;
    }

    @Override
    public Inventory getInventoryByTrayCode() {
        String trayCode = receiptService.getTrayCode();
        if (null == trayCode || "".equals(trayCode)) {
            return null;
        }
        Inventory byTrayCodeTop = inventoryRepository.findByTrayCodeTop(trayCode);
        if (null != byTrayCodeTop) {
            return byTrayCodeTop;
        }
        return null;
    }

    @Override
    public Inventory queryInventoryByBoxNumber(String boxNumber) {
        return null;
    }

    @Override
    public Map<String, Object> outBoundByDoc(String param) {
        if (null == param || "".equals(param)) {
            return null;
        }
        Tasks tasks = tasksRepository.findBySourceCodeTop(param);
        if (null != tasks) {
            if (tasks.getTaskType() == 14) {
                List<TaskDetail> taskDetailList = taskDetailRepository.getTaskDetailsByTaskId(tasks.getId());
                String lotNo = taskDetailList.get(0).getLotNo();
                String remk = "冻结";
                //根据物料号和类型查找库存
                List<Inventory> inventoryList = inventoryRepository.findByLotCodeAndGrade(lotNo);
                //返回类型和库存集合
                Map<String, Object> map = new HashMap<>();
                map.put("inventoryList", inventoryList);
                map.put("type", remk);
                return map;
            } else if (tasks.getTaskType() == 15) {
                List<TaskDetail> taskDetailList = taskDetailRepository.getTaskDetailsByTaskId(tasks.getId());
                String elNo = taskDetailList.get(0).getEl_no();
                String lotNo = taskDetailList.get(0).getLotNo();
                String remk = "解冻";
                //根据物料号和类型查找库存
                List<Inventory> inventoryList = inventoryRepository.findByLotCodeAndElNo(lotNo, elNo);
                //返回类型和库存集合
                Map<String, Object> map = new HashMap<>();
                map.put("inventoryList", inventoryList);
                map.put("type", remk);
                return map;
            }
        }
        return null;
    }

    @Override
    public Inventory findInventoryByTrayCode() {
        String trayCode = receiptService.getTrayCode();
        if (null != trayCode && !"".equals(trayCode)) {
            return inventoryRepository.findByTrayCodeTop(trayCode);
        }
        return null;
    }

    @Override
    public String returnLocationByBoxNumber(String param) {
        //冻结回库，先删掉库存
        String trayCode = receiptService.getTrayCode();
        if (trayCode.equals("")) {
            return "fail";
        }
        Inventory inventory = inventoryRepository.findByBoxNumber(param);
        inventoryRepository.delete(inventory);
        String kuQu = "";
        if (trayCode.contains("A")) {
            kuQu = "%CW%";
        } else {
            kuQu = "%HW%";
        }
        List<Location> locations = locationRepository.findByStatus("0", kuQu);
        if (null != locations && locations.size() > 0) {

        }
        //检索空库位回库
        return null;
    }

    @Override
    public String outBoundByZanCun(String param) {
        List<String> list = JSON.parseArray(param, String.class);
        Snowflake snowflake = new Snowflake();
        List<Inventory> inventoryList = inventoryRepository.findByIdList(list);
        if (null != inventoryList && inventoryList.size() > 0) {
            JSONObject agvTask = new JSONObject();
            agvTask.put("taskType", "tote_outbound");
//            agvTask.put("groupPriority", 1);
            agvTask.put("taskGroupCode", UuidUtil.genCode());
            Tasks wmsTasks = new Tasks();
            wmsTasks.setId(snowflake.nextIdStr());
            wmsTasks.setTaskCode(UuidUtil.genCode());
            wmsTasks.setStatus(1);
            wmsTasks.setRemark("立库出到暂存区");
            wmsTasks.setLocationTo("暂存区");
            List<JSONObject> tasks = new ArrayList<>();
            for (Inventory inventory : inventoryList) {
                if (inventory.getWarehouseLocation().equals("暂存区")) {
                    continue;
                }
                JSONObject task = new JSONObject();
                TaskDetail taskDetail = new TaskDetail();
                taskDetail.setId(UuidUtil.genCode());
                taskDetail.setTaskId(wmsTasks.getId());
                taskDetail.setStatus(1);
                taskDetail.setIsZanCun(1);
                taskDetail.setTaskCode(snowflake.nextIdStr());
                taskDetail.setEl_no(inventory.getMaterialCode());
                taskDetail.setInvCount(inventory.getAvailableQuantity());
                taskDetail.setType("立库出到暂存区");
                taskDetail.setEl_unit(inventory.getElUnit());
                taskDetail.setPkQty(inventory.getAvailableQuantity());
                taskDetail.setElName(inventory.getMaterialName());
                taskDetail.setTrayCode(inventory.getTrayCode());
                taskDetail.setPkList(inventory.getBoxNumber());
                taskDetail.setZoneCode(inventory.getZoneCode());
                taskDetail.setWaNo(inventory.getWaNo());
                taskDetail.setSuNo(inventory.getSuNo());
                taskDetail.setLotNo(inventory.getLotCode());
                taskDetail.setVmiCode(inventory.getVmiCode());
                taskDetail.setSourceId("");
                taskDetailRepository.save(taskDetail);
                //agv任务详细
                JSONObject taskDescribe = new JSONObject();
                taskDescribe.put("containerCode", inventory.getTrayCode());
                taskDescribe.put("storageTag", "");
                taskDescribe.put("fromLocationCode", "");
                List<String> toLocationCode = new ArrayList<>();
                toLocationCode.add("CY01");
                taskDescribe.put("toStationCode", toLocationCode);
                String code = snowflake.nextIdStr();
                AgvTasks agvTasks = new AgvTasks();
                agvTasks.setId(snowflake.nextIdStr());
                agvTasks.setTaskType("立库出暂存区");
                agvTasks.setBillNumber(code);
                agvTasks.setGroupPriority(1);
                agvTasks.setStatus(1);
                task.put("taskCode", code);
                task.put("taskPriority", 1);
                task.put("taskDescribe", taskDescribe);
                tasks.add(task);
                agvTasksRepository.save(agvTasks);
            }
            agvTask.put("tasks", tasks);
            if (tasks.size() > 0) {
                String s = commonUtil.httpPost("http://" + agvIp + ":" + agvPort + "/task/create", JSON.toJSONString(agvTask));
                Result result = JSON.parseObject(s, Result.class);
                log.info("立库出暂存区收到agv反馈" + result);
                if (result.getCode() != 0) {
                    return null;
                } else {
                    return "success";
                }
            }
        } else {
            return "fail";
        }

        return null;
    }

    @Override
    public int receiveFreezeInventoryBillNumberFromPDA(String param) {
        try {
            JSONObject jsonObject = JSON.parseObject(param);
            String billNumber = jsonObject.getString("billNumber");
            WebSocketServer.sendInfo(new SocketMsg(billNumber, MsgType.INFO), "999");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int autoTally() {
        /** 查询所有四层以下的不足2箱的物料编码和库存箱数（常温库） */
        List<Map<String, Object>> inventoryNeedTallyList = inventoryRepository.autoTallyInventorySelect();

        /** 查询所有四层以下的不足1箱的物料编码和库存箱数（恒温库--过载保护器） */
        List<Map<String, Object>> inventoryNeedTallyListHW = inventoryRepository.autoTallyInventorySelectHW();

        List<TallyTasks> tallyTasksList = new ArrayList<>();

        /** 查重，如果系统内还有剩余的理货任务，则不允许下发新的理货任务 */
        TallyTasks tallyTasksExist = tallyTasksRepository.getFirstTallyTask();
        if (null != tallyTasksExist) {
            return 2; // 之前的理货任务未结束，不允许添加新的理货任务
        }

        /** 处理常温库 */
        for (int i = 0; i < inventoryNeedTallyList.size(); i++) {
            Map<String, Object> tallyMap = inventoryNeedTallyList.get(i);
            int num = (int) tallyMap.get("num");
            String materialCode = tallyMap.get("material_code_1").toString();
            String materialName = tallyMap.get("material_name_1").toString();

            TallyTasks tallyTasks = new TallyTasks();
            tallyTasks.setId(IdUtil.simpleUUID());
            tallyTasks.setQty(num);
            tallyTasks.setMaterialCode(materialCode);
            tallyTasks.setMaterialName(materialName);
            tallyTasks.setStatus(0);    // 未开始
            tallyTasksList.add(tallyTasks);

        }

        /** 处理恒温库 */
        for (int i = 0; i < inventoryNeedTallyListHW.size(); i++) {
            Map<String, Object> tallyMap = inventoryNeedTallyListHW.get(i);
            int num = (int) tallyMap.get("num");
            String materialCode = tallyMap.get("material_code_1").toString();
            String materialName = tallyMap.get("material_name_1").toString();

            TallyTasks tallyTasks = new TallyTasks();
            tallyTasks.setId(IdUtil.simpleUUID());
            tallyTasks.setQty(num);
            tallyTasks.setMaterialCode(materialCode);
            tallyTasks.setMaterialName(materialName);
            tallyTasks.setStatus(0);    // 未开始
            tallyTasksList.add(tallyTasks);

        }
        tallyTasksRepository.saveAll(tallyTasksList);

        /** 开始执行一次, 其他的任务在AGV完成上一条的回调时再执行 */
        int result = generateTallyTasks();

        return result;
    }

    @Override
    public Map<String, Object> getInventoryGroupByMaterialCode(InventoryQueryCriteria criteria, Pageable pageable) {
        String locationCode = criteria.getLocationCode();
        String warehouseCode = criteria.getWarehouseCode();
        String trayCode = criteria.getTrayCode();
        String materialName = criteria.getMaterialName();
        String materialCode = criteria.getMaterialCode();
        String lotCode = criteria.getLotCode();
        String grade = criteria.getGrade();
        String pkList = criteria.getBoxNumber();
        String warehouseLocation = criteria.getWarehouseLocation();
        String zoneCode = criteria.getZoneCode();
        String queryCondition = getWhereCondition(warehouseLocation, locationCode, warehouseCode, trayCode, materialName, materialCode, lotCode, grade, pkList, zoneCode);

        String sql = "select sum(available_quantity) as available_quantity, SUM ( hold_quantity ) +  SUM(available_quantity) AS total, SUM ( hold_quantity ) AS hold_quantity, material_code, material_name from inventory "
                + queryCondition +
                " GROUP BY material_code, material_name ORDER BY material_code OFFSET (" + pageable.getPageNumber() * pageable.getPageSize() + ") ROWS FETCH NEXT " + pageable.getPageSize() + " ROWS ONLY";

        List<Map<String, Object>> inventoryListGroupByMaterialCodeWithOffset = jdbcTemplate.queryForList(sql);

        String sql2 = "select sum(available_quantity) as available_quantity, SUM ( hold_quantity ) +  SUM(available_quantity) AS total, SUM ( hold_quantity ) AS hold_quantity, material_code, material_name from inventory "
                + queryCondition +
                " GROUP BY material_code, material_name ";
        List<Map<String, Object>> inventoryListCount = jdbcTemplate.queryForList(sql2);
//        List<Map<String, Object>> inventoryListGroupByMaterialCodeWithOffset = inventoryRepository.getInventoryGroupByMaterial(pageable.getPageNumber(), pageable.getPageSize(), queryCondition);
//        List<Map<String, Object>> inventoryListCount = inventoryRepository.getCount();
        Map<String, Object> objectMap = new HashMap<>();
        objectMap.put("content", inventoryListGroupByMaterialCodeWithOffset);
        objectMap.put("totalElements", inventoryListCount.size());


        return objectMap;
    }

    @Override
    public int generateTallyTasks() {
        TallyTasks tallyTasks = tallyTasksRepository.getFirstTallyTask();
        String materialCode = tallyTasks.getMaterialCode();
        String materialName = tallyTasks.getMaterialName();
        int qty = tallyTasks.getQty();

        /** 修改理货状态, 和表格中4层下的数量 */
        tallyTasks.setQty(qty + 1);

        int needTallyNum = 0;

        if (materialName.equals("过载保护器")) { // 恒温库，四层一下1箱
            needTallyNum = 1;
            tallyTasks.setStatus(2);    // 全部完成
        } else {    // 常温库，4层一下2箱
            needTallyNum = 2 - qty;
            if (needTallyNum == 2) {
                tallyTasks.setStatus(1);    // 部分完成
            } else if (needTallyNum == 1) {
                tallyTasks.setStatus(2);    // 全部完成
            }
        }
        tallyTasksRepository.save(tallyTasks);

        List<Inventory> inventoryList = inventoryRepository.getInventoriesByMaterialCodeOrderByElMkDateAscWithLayerGreaterThen4(materialCode, needTallyNum);
        if (inventoryList.size() > 0) { // 如果该物料有满足条件的四层以上的物料，如果没有4层以上的就不用理货了
            for (Inventory inventory : inventoryList) {
                /** 判断库存的类别 */
                Location location = locationRepository.getLocationsByLocationCode(inventory.getLocationCode());
                int locationType = location.getType();

                /** 筛选一个四层一下的空料箱库位 */
                Location locationUnder4 = null;
                List<Location> locationList = locationRepository.getLocationsByQtyAndTypeWithLayerLessThen4(1, locationType);
                if (locationList.size() == 0) {    // 异常排除，在4层下没有空料箱的情况，查询哪一种物料在4层以下的库存是大于4箱的
                    Inventory locationWithInventory = inventoryRepository.getInventoryByMaterialCodeWithMostQtyLessThenLayer4();
                    locationUnder4 = locationRepository.findLocationByLocationCode(locationWithInventory.getWarehouseLocation());
                } else {
                    locationUnder4 = locationList.get(0);
                }

                /** 再筛选一个空库位 */
                List<Location> locationList2 = locationRepository.getEmptyLocationsByQtyAndTypeOrderByLayerDesc(1, locationType);
                Location locationEmpty = locationList2.get(0);
                /** 禁用库位 */
                locationEmpty.setStatus(2); // 2--禁用
                locationRepository.save(locationEmpty);

                /** 生成理货任务, 先把空料箱搬运到空库位 */
                Tasks tasks = new Tasks();
                tasks.setId(IdUtil.simpleUUID());
                tasks.setTaskType(12);  // 12--移库
                tasks.setTaskCode(UuidUtil.genCode());
                tasks.setStatus(1); // 1--执行中
                tasks.setElName("料箱");
                tasks.setTrayCode(locationUnder4.getTrayCode());
                tasks.setMtQty(new BigDecimal(1));
                tasks.setLocationFrom(locationUnder4.getLocationCode());
                tasks.setLocationTo(locationEmpty.getLocationCode());
                tasks.setElUnit("个");
                tasksRepository.save(tasks);

                /** 生成TaskDetail */
                TaskDetail taskDetail = new TaskDetail();
                taskDetail.setId(IdUtil.simpleUUID());
                taskDetail.setTaskCode(UuidUtil.genCode());
                taskDetail.setTaskId(tasks.getId());
                taskDetailRepository.save(taskDetail);

                /** 搬运需要理货的有物料料箱到新挪出来的4层下库位, 先生成任务，暂时不下发给AGV */
                Tasks tasks2 = new Tasks();
                tasks2.setId(IdUtil.simpleUUID());
                tasks2.setTaskType(12);  // 12--移库
                tasks2.setTaskCode(UuidUtil.genCode());
                tasks2.setStatus(0); // 0--未开始
                tasks2.setElName(inventory.getMaterialName());
                tasks2.setTrayCode(inventory.getTrayCode());
                tasks2.setMtQty(new BigDecimal(1));
                tasks2.setLocationFrom(inventory.getWarehouseLocation());
                tasks2.setLocationTo(locationUnder4.getLocationCode());
                tasks2.setElUnit(inventory.getElUnit());
                tasks2.setSourceCode(tasks.getTaskCode());
                tasksRepository.save(tasks2);

                /** 生成物料移库任务 */
                TaskDetail taskDetail2 = new TaskDetail();
                taskDetail2.setId(IdUtil.simpleUUID());
                taskDetail2.setBoxNumber(locationEmpty.getTrayCode());
                taskDetail2.setTaskCode(UuidUtil.genCode());
                taskDetail2.setTrayCode(inventory.getTrayCode());
                taskDetail2.setPkList(inventory.getBoxNumber());
                taskDetail2.setPkQty(inventory.getTotal());
                taskDetail2.setSuNo(inventory.getSuNo());
                taskDetail2.setWaNo(inventory.getWaNo());
                taskDetail2.setLotNo(inventory.getLotCode());
                taskDetail2.setVmiCode(inventory.getVmiCode());
                taskDetail2.setSourceId(taskDetail.getTaskCode());
                taskDetail2.setTaskId(tasks2.getId());
                taskDetailRepository.save(taskDetail2);

                /** 新建AGV任务 */
                AgvTasks agvTasks = new AgvTasks();
                agvTasks.setId(UuidUtil.genCode());
                agvTasks.setBillNumber(tasks.getTaskCode());
                agvTasks.setTaskGroupCode(UuidUtil.genCode());
                agvTasks.setTaskType("移库");
                agvTasks.setStatus(1);  // 1--执行中
                agvTasks.setGroupPriority(0);   // 优先级
                agvTasksRepository.save(agvTasks);

                AgvTaskDetail agvTaskDetail = new AgvTaskDetail();
                agvTaskDetail.setId(IdUtil.simpleUUID());
                agvTaskDetail.setTaskCode(UuidUtil.genCode());
                agvTaskDetail.setTaskPriority(0);
                agvTaskDetail.setStatus(1); // 1--执行中
                agvTaskDetail.setContainerCode(locationUnder4.getTrayCode());
                agvTaskDetail.setContainerType("CT_KUBOT_STANDARD");
                agvTaskDetail.setFromLocationCode(locationUnder4.getLocationCode());
                agvTaskDetail.setToLocationCode(locationEmpty.getLocationCode());
                agvTaskDetail.setMainId(agvTasks.getId());
                agvTaskDetail.setSourceCode(tasks.getTaskCode());
                agvTaskDetailRepository.save(agvTaskDetail);

                /** 新建二段的AGV任务 */
                AgvTasks agvTasks2 = new AgvTasks();
                agvTasks2.setId(UuidUtil.genCode());
                agvTasks2.setBillNumber(tasks2.getTaskCode());
                agvTasks2.setTaskGroupCode(UuidUtil.genCode());
                agvTasks2.setTaskType("移库");
                agvTasks2.setStatus(0);  // 0--未执行
                agvTasks2.setGroupPriority(0);   // 优先级
                agvTasksRepository.save(agvTasks2);

                AgvTaskDetail agvTaskDetail2 = new AgvTaskDetail();
                agvTaskDetail2.setId(IdUtil.simpleUUID());
                agvTaskDetail2.setTaskCode(UuidUtil.genCode());
                agvTaskDetail2.setTaskPriority(0);
                agvTaskDetail2.setStatus(0); // 0--未执行
                agvTaskDetail2.setContainerCode(inventory.getTrayCode());
                agvTaskDetail2.setContainerType("CT_KUBOT_STANDARD");
                agvTaskDetail2.setFromLocationCode(inventory.getWarehouseLocation());
                agvTaskDetail2.setToLocationCode(locationUnder4.getLocationCode());
                agvTaskDetail2.setMainId(agvTasks2.getId());
                agvTaskDetail2.setSourceCode(tasks2.getTaskCode());
                agvTaskDetailRepository.save(agvTaskDetail2);

                /** 下发给AGV */
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("taskType", "carry");
                jsonObject1.put("taskGroupCode", agvTasks.getTaskGroupCode());
//                jsonObject1.put("groupPriority", 1);
                JSONArray jsonArray = new JSONArray();

                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("taskCode", tasks.getTaskCode());   // WMS-tasks主表任务号，这里发送给AGV的任务号， AGV回调以后会返回这个任务号给我。这里不严谨，但是延续之前的逻辑，不做更改了
                jsonObject2.put("taskPriority", 1);

                JSONObject jsonObject3 = new JSONObject();
                jsonObject3.put("containerCode", agvTaskDetail.getContainerCode()); // 料箱号
                jsonObject3.put("storageTag", "");   // 留空
                jsonObject3.put("containerType", "");
                jsonObject3.put("fromLocationCode", agvTaskDetail.getFromLocationCode());    // 起始库位号
                jsonObject3.put("toLocationCode", agvTaskDetail.getToLocationCode());    // 目标库位号
                jsonObject3.put("toStationCode", "");   // 出库的目标操作台编号 留空

                jsonObject2.put("taskDescribe", jsonObject3);
                jsonArray.add(jsonObject2);

                jsonObject1.put("tasks", jsonArray);
                String url = "http://" + agvIp + ":" + agvPort + "/task/create";
                log.info("空料箱移库任务，发送给AGV, " + jsonObject1);
                String resp = commonUtil.httpPost(url, jsonObject1);
                Result result = JSON.parseObject(resp, Result.class);
                log.info("空料箱移库任务，接收到AGV反馈, " + resp);
                if (result.getCode() != 0) {
                    log.info(agvTasks.getTaskGroupCode() + ", 移库任务AGV响应异常，原因：" + result);
                    agvTasks.setStatus(3);  // 3--异常
                    agvTasksRepository.save(agvTasks);
                    return 3;
                } else {
                    /** 修改任务状态 */
                    tasks.setStatus(1); // 执行中
                    tasksRepository.save(tasks);
                    /** 创建了一条理货任务后，需要跳出循环 */
                    return 1;
                }
            }
        } else {
            /** 4层以上没有库存了，这时候也要结束任务 */
            tallyTasks.setStatus(2);    //  4层上库存不足
            tallyTasksRepository.save(tallyTasks);
        }

        return 1;
    }

    private String getWhereCondition(String warehouseLocation, String locationCode, String warehouseCode, String trayCode, String materialName, String materialCode, String lotCode, String grade, String pkList, String zoneCode) {
        String queryCondition = "";
        if (commonUtil.isStringNotEmpty(locationCode)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where warehouse_location like '%" + locationCode + "%'";
            } else {
                queryCondition = queryCondition + " and warehouse_location like '%" + locationCode + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(warehouseLocation)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where warehouse_location like '%" + warehouseLocation + "%'";
            } else {
                queryCondition = queryCondition + " and warehouse_location like '%" + warehouseLocation + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(warehouseCode)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where warehouse_code like '%" + warehouseCode + "%'";
            } else {
                queryCondition = queryCondition + " and warehouse_code like '%" + warehouseCode + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(trayCode)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where traycode like '%" + trayCode + "%'";
            } else {
                queryCondition = queryCondition + " and traycode like '%" + trayCode + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(materialName)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where material_name like '%" + materialName + "%'";
            } else {
                queryCondition = queryCondition + " and material_name like '%" + materialName + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(materialCode)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where material_code like '%" + materialCode + "%'";
            } else {
                queryCondition = queryCondition + " and material_code like '%" + materialCode + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(lotCode)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where lot_code like '%" + lotCode + "%'";
            } else {
                queryCondition = queryCondition + " and lot_code like '%" + lotCode + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(grade)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where grade like '%" + grade + "%'";
            } else {
                queryCondition = queryCondition + " and grade like '%" + grade + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(pkList)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where box_number like '%" + pkList + "%'";
            } else {
                queryCondition = queryCondition + " and box_number like '%" + pkList + "%'";
            }
        }
        if (commonUtil.isStringNotEmpty(zoneCode)) {
            if (queryCondition.equals("")) {
                queryCondition = queryCondition + "where zone_code like '%" + zoneCode + "%'";
            } else {
                queryCondition = queryCondition + " and zone_code like '%" + zoneCode + "%'";
            }
        }
        return queryCondition;
    }
}